package cn.heyige.backend.algorithm;

import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 城市五行数据管理类
 * 
 * 管理城市与五行的对应关系，以及基于反馈的动态权重调整
 */
@Slf4j
public class CityElementData {

    // 城市卦象权重调整缓存（城市 -> 卦象 -> 权重调整值）
    private static final Map<String, Map<String, Double>> CITY_HEXAGRAM_WEIGHTS = new ConcurrentHashMap<>();

    // 城市方位五行映射（基于传统风水理论）
    private static final Map<String, String> CITY_DIRECTION_ELEMENTS = new HashMap<>();

    static {
        // 初始化城市方位五行数据（基于中国传统地理风水）
        initializeCityDirectionElements();
    }

    /**
     * 初始化城市方位五行数据
     */
    private static void initializeCityDirectionElements() {
        // 华北地区（土）
        CITY_DIRECTION_ELEMENTS.put("北京", "土");
        CITY_DIRECTION_ELEMENTS.put("天津", "水");
        CITY_DIRECTION_ELEMENTS.put("石家庄", "土");
        CITY_DIRECTION_ELEMENTS.put("太原", "土");
        CITY_DIRECTION_ELEMENTS.put("呼和浩特", "土");

        // 东北地区（水）
        CITY_DIRECTION_ELEMENTS.put("沈阳", "水");
        CITY_DIRECTION_ELEMENTS.put("长春", "水");
        CITY_DIRECTION_ELEMENTS.put("哈尔滨", "水");
        CITY_DIRECTION_ELEMENTS.put("大连", "水");

        // 华东地区（木）
        CITY_DIRECTION_ELEMENTS.put("上海", "水"); // 临海，水性强
        CITY_DIRECTION_ELEMENTS.put("南京", "木");
        CITY_DIRECTION_ELEMENTS.put("杭州", "木");
        CITY_DIRECTION_ELEMENTS.put("苏州", "木");
        CITY_DIRECTION_ELEMENTS.put("合肥", "木");
        CITY_DIRECTION_ELEMENTS.put("福州", "木");
        CITY_DIRECTION_ELEMENTS.put("南昌", "火"); // 偏南，火性
        CITY_DIRECTION_ELEMENTS.put("济南", "土");
        CITY_DIRECTION_ELEMENTS.put("青岛", "水");

        // 华南地区（火）
        CITY_DIRECTION_ELEMENTS.put("广州", "火");
        CITY_DIRECTION_ELEMENTS.put("深圳", "火");
        CITY_DIRECTION_ELEMENTS.put("珠海", "火");
        CITY_DIRECTION_ELEMENTS.put("汕头", "火");
        CITY_DIRECTION_ELEMENTS.put("厦门", "水"); // 临海
        CITY_DIRECTION_ELEMENTS.put("海口", "火");
        CITY_DIRECTION_ELEMENTS.put("南宁", "火");

        // 华中地区（土/火）
        CITY_DIRECTION_ELEMENTS.put("武汉", "火");
        CITY_DIRECTION_ELEMENTS.put("长沙", "火");
        CITY_DIRECTION_ELEMENTS.put("郑州", "土");

        // 西南地区（土）
        CITY_DIRECTION_ELEMENTS.put("重庆", "火"); // 山城，火性
        CITY_DIRECTION_ELEMENTS.put("成都", "土");
        CITY_DIRECTION_ELEMENTS.put("贵阳", "土");
        CITY_DIRECTION_ELEMENTS.put("昆明", "木"); // 春城，木性
        CITY_DIRECTION_ELEMENTS.put("拉萨", "土");

        // 西北地区（金）
        CITY_DIRECTION_ELEMENTS.put("西安", "土");
        CITY_DIRECTION_ELEMENTS.put("兰州", "金");
        CITY_DIRECTION_ELEMENTS.put("西宁", "金");
        CITY_DIRECTION_ELEMENTS.put("银川", "金");
        CITY_DIRECTION_ELEMENTS.put("乌鲁木齐", "金");
    }

    /**
     * 获取城市的五行属性
     *
     * @param city 城市名称
     * @return 五行属性
     */
    public static String getCityElement(String city) {
        if (city == null || city.isEmpty()) {
            return "土"; // 默认土
        }

        // 清理城市名称
        String cleanCity = city.replaceAll("[市县区]", "");
        
        // 优先从方位五行映射中获取
        String element = CITY_DIRECTION_ELEMENTS.get(cleanCity);
        if (element != null) {
            return element;
        }

        // 回退到原有的城市五行映射
        return DataConstant.CITY_FIVE_ELEMENTS.getOrDefault(cleanCity, "土");
    }

    /**
     * 调整城市卦象权重
     *
     * @param city 城市名称
     * @param hexagram 卦象名称
     * @param increase 是否增加权重
     */
    public static void adjustCityHexagramWeight(String city, String hexagram, boolean increase) {
        if (city == null || hexagram == null) {
            return;
        }

        String cleanCity = city.replaceAll("[市县区]", "");
        
        CITY_HEXAGRAM_WEIGHTS.computeIfAbsent(cleanCity, k -> new ConcurrentHashMap<>());
        
        Map<String, Double> hexagramWeights = CITY_HEXAGRAM_WEIGHTS.get(cleanCity);
        double currentWeight = hexagramWeights.getOrDefault(hexagram, 0.0);
        
        // 调整权重（增加或减少0.1）
        double adjustment = increase ? 0.1 : -0.1;
        double newWeight = Math.max(-1.0, Math.min(1.0, currentWeight + adjustment));
        
        hexagramWeights.put(hexagram, newWeight);
        
        log.debug("调整城市卦象权重: {}_{} -> {}", cleanCity, hexagram, newWeight);
    }

    /**
     * 获取城市卦象权重
     *
     * @param city 城市名称
     * @param hexagram 卦象名称
     * @return 权重值（-1.0到1.0之间）
     */
    public static double getCityHexagramWeight(String city, String hexagram) {
        if (city == null || hexagram == null) {
            return 0.0;
        }

        String cleanCity = city.replaceAll("[市县区]", "");
        
        Map<String, Double> hexagramWeights = CITY_HEXAGRAM_WEIGHTS.get(cleanCity);
        if (hexagramWeights == null) {
            return 0.0;
        }
        
        return hexagramWeights.getOrDefault(hexagram, 0.0);
    }

    /**
     * 根据城市地理特征计算五行强度
     *
     * @param city 城市名称
     * @return 五行强度映射
     */
    public static Map<String, Double> getCityElementStrengths(String city) {
        Map<String, Double> strengths = new HashMap<>();
        
        // 初始化所有五行为平均值
        strengths.put("木", 1.0);
        strengths.put("火", 1.0);
        strengths.put("土", 1.0);
        strengths.put("金", 1.0);
        strengths.put("水", 1.0);
        
        if (city == null || city.isEmpty()) {
            return strengths;
        }

        String cleanCity = city.replaceAll("[市县区]", "");
        String primaryElement = getCityElement(cleanCity);
        
        // 主要五行增强
        strengths.put(primaryElement, 1.3);
        
        // 根据城市特征进一步调整
        adjustCitySpecificStrengths(cleanCity, strengths);
        
        return strengths;
    }

    /**
     * 根据城市特征调整五行强度
     */
    private static void adjustCitySpecificStrengths(String city, Map<String, Double> strengths) {
        // 沿海城市水性增强
        if (isCoastalCity(city)) {
            strengths.put("水", strengths.get("水") + 0.2);
        }
        
        // 山区城市土性增强
        if (isMountainCity(city)) {
            strengths.put("土", strengths.get("土") + 0.2);
        }
        
        // 工业城市金性增强
        if (isIndustrialCity(city)) {
            strengths.put("金", strengths.get("金") + 0.2);
        }
        
        // 南方城市火性增强
        if (isSouthernCity(city)) {
            strengths.put("火", strengths.get("火") + 0.1);
        }
        
        // 北方城市水性增强
        if (isNorthernCity(city)) {
            strengths.put("水", strengths.get("水") + 0.1);
        }
    }

    /**
     * 判断是否为沿海城市
     */
    private static boolean isCoastalCity(String city) {
        String[] coastalCities = {"上海", "天津", "大连", "青岛", "厦门", "深圳", "广州", 
                                 "珠海", "汕头", "海口", "三亚", "宁波", "温州", "烟台", "威海"};
        for (String coastal : coastalCities) {
            if (city.contains(coastal)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否为山区城市
     */
    private static boolean isMountainCity(String city) {
        String[] mountainCities = {"重庆", "昆明", "贵阳", "拉萨", "西宁", "兰州", "太原", "西安"};
        for (String mountain : mountainCities) {
            if (city.contains(mountain)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否为工业城市
     */
    private static boolean isIndustrialCity(String city) {
        String[] industrialCities = {"沈阳", "大连", "天津", "青岛", "苏州", "无锡", "佛山", "东莞"};
        for (String industrial : industrialCities) {
            if (city.contains(industrial)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否为南方城市
     */
    private static boolean isSouthernCity(String city) {
        String[] southernCities = {"广州", "深圳", "珠海", "汕头", "厦门", "福州", "南宁", 
                                  "海口", "长沙", "南昌", "重庆", "成都", "昆明"};
        for (String southern : southernCities) {
            if (city.contains(southern)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否为北方城市
     */
    private static boolean isNorthernCity(String city) {
        String[] northernCities = {"北京", "天津", "沈阳", "长春", "哈尔滨", "石家庄", 
                                  "太原", "呼和浩特", "西安", "兰州", "西宁", "银川", "乌鲁木齐"};
        for (String northern : northernCities) {
            if (city.contains(northern)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 清除权重缓存
     */
    public static void clearWeightCache() {
        CITY_HEXAGRAM_WEIGHTS.clear();
        log.info("已清除城市卦象权重缓存");
    }

    /**
     * 获取所有城市权重统计
     */
    public static Map<String, Map<String, Double>> getAllCityWeights() {
        return new HashMap<>(CITY_HEXAGRAM_WEIGHTS);
    }
}